function Tests = exogenizeTest()
Tests = functiontests(localfunctions) ;
end


%**************************************************************************


function setupOnce(This) %#ok<*DEFNU>
rng(0);
m = model('credibility.model');
m.alp = 0.5;
m.sgm = 0.1;
m.bet = 0.99;
m.gam = 0.05;
m.del = 0.4;
m.the = 0.80;
m.kap = 4;
m.phi = 0;
m.tau = 3;
m.rho = 2;
m.psi = 0.9;
m.omg = 1;
m = sstate(m,'display=','none','blocks=',true,'growth=',true);
chksstate(m);
m = solve(m);
This.TestData.Model = m;

nonlinOpt = {'method=','selective','tolerance=',1e-10, ...
    'maxIter=',1000,'display=',0};
This.TestData.NonlinOpt = nonlinOpt;
end % setupOnce()


%**************************************************************************


function testResimulate(This)
m = This.TestData.Model;
nonlinOpt = This.TestData.NonlinOpt;
startDate = qq(2000,1);
endDate = startDate+19;
range = startDate : endDate;

exgDates = startDate+(5:6);
endgDates = startDate+(15:16);
p = plan(m,range);
p = exogenize(p,exgDates,'y');
p = endogenize(p,endgDates,'ey');
d = sstatedb(m,range);
d.y(exgDates) = d.y(exgDates)+rand(length(exgDates),1)/10;

s1 = simulate(m,d,range,'plan=',p,nonlinOpt{:});
s2 = simulate(m,s1,range,nonlinOpt{:});
x1 = lhsmrhs(m,s1,range(5:end));
x2 = lhsmrhs(m,s2,range(5:end));

assertEqual(This,s1.y(exgDates),d.y(exgDates),'AbsTol',1e-14);
assertEqual(This,s1.y(:),s2.y(:),'AbsTol',1e-8);
assertLessThan(This,maxabs(x1),1e-10);
assertLessThan(This,maxabs(x2),1e-10);
end % testResimulate()


%**************************************************************************


function testTransitionVsMeasurement(This)
m = This.TestData.Model;
nonlinOpt = This.TestData.NonlinOpt;
startDate = qq(2000,1);
endDate = startDate+19;
range = startDate : endDate;

exgDates = startDate+(5:6);
endgDates = startDate+(15:16);

p1 = plan(m,range);
p1 = exogenize(p1,exgDates,'y');
p1 = endogenize(p1,endgDates,'ey');
d1 = sstatedb(m,range);
d1.y(exgDates) = d1.y(exgDates)+rand(length(exgDates),1)/10;
s1 = simulate(m,d1,range,'plan=',p1,nonlinOpt{:});

p2 = plan(m,range);
p2 = exogenize(p2,exgDates,'Y');
p2 = endogenize(p2,endgDates,'ey');
d2 = sstatedb(m,range);
d2.Y(exgDates) = d1.y(exgDates);
s2 = simulate(m,d2,range,'plan=',p2,nonlinOpt{:});

assertEqual(This,s1.y(exgDates),d1.y(exgDates),'AbsTol',1e-14);
assertEqual(This,s2.Y(exgDates),d2.Y(exgDates),'AbsTol',1e-14);
assertEqual(This,s1.y(:),s2.y(:),'AbsTol',1e-8);
end % testTransitionVsMeasurement()


%**************************************************************************


function testLongEndg(This)
m = This.TestData.Model;
nonlinOpt = This.TestData.NonlinOpt;
startDate = qq(2000,1);
endDate = startDate+19;
range = startDate : endDate;

exgDates = startDate+(5:6);
endgDates = startDate+(15:16);

N = 10;
p1 = plan(m,range);
p1 = exogenize(p1,exgDates,'y');
p1 = endogenize(p1,endgDates,'ey');
d1 = sstatedb(m,range);
d1.y(exgDates) = d1.y(exgDates)+rand(length(exgDates),1)/10;
s1 = simulate(m,d1,range,'plan=',p1,nonlinOpt{:},'nonlinPer=',N);
x1 = lhsmrhs(m,s1,range(5:N));

assertEqual(This,s1.y(exgDates),d1.y(exgDates),'AbsTol',1e-14);
assertLessThan(This,maxabs(x1),1e-10);
end % testLongEndg()


%**************************************************************************


function testLongExg(This)
m = This.TestData.Model;
nonlinOpt = This.TestData.NonlinOpt;
startDate = qq(2000,1);
endDate = startDate+19;
range = startDate : endDate;

exgDates = startDate+(15:16);
endgDates = startDate+(5:6);

N = 10;
p1 = plan(m,range);
p1 = exogenize(p1,exgDates,'y');
p1 = endogenize(p1,endgDates,'ey');
d1 = sstatedb(m,range);
d1.y(exgDates) = d1.y(exgDates)+rand(length(exgDates),1)/10;
s1 = simulate(m,d1,range,'plan=',p1,nonlinOpt{:},'nonlinPer=',N);
x1 = lhsmrhs(m,s1,range(5:N));

assertEqual(This,s1.y(exgDates),d1.y(exgDates),'AbsTol',1e-14);
assertLessThan(This,maxabs(x1),1e-10);
end % testLongExg()


%**************************************************************************


function testDeviation(This)
m = This.TestData.Model;
nonlinOpt = This.TestData.NonlinOpt;
startDate = qq(2000,1);
endDate = startDate+19;
range = startDate : endDate;
range = range(1:6);

exgDates = startDate+(0:4);
endgDates = startDate+(0:4);

x = rand(length(exgDates),1)/10;

p1 = plan(m,range);
p1 = exogenize(p1,exgDates,'p');
p1 = endogenize(p1,endgDates,'epi');
d1 = sstatedb(m,range);
d1.p(exgDates) = d1.p(exgDates) + x;
s1 = simulate(m,d1,range,'plan=',p1,nonlinOpt{:},'anticipate=',false);

assertEqual(This,s1.p(exgDates),d1.p(exgDates),'AbsTol',1e-14);

p2 = p1;
d2 = zerodb(m,range);
d2.p(exgDates) = d2.p(exgDates) + x;
s2 = simulate(m,d2,range,'plan=',p2,nonlinOpt{:}, ...
    'anticipate=',false,'deviation=',true);

assertEqual(This,s2.p(exgDates),d2.p(exgDates),'AbsTol',1e-14);
assertEqual(This,s1.epi(:),s2.epi(:),'AbsTol',1e-14);
end % testDeviation()
